﻿namespace Lite.Messaging
{
    /// <summary>
    /// The base interface for accessing a single message
    /// </summary>
    public interface IMessage
    {
        /// <summary>
        /// Gets a globally unique identifier to link this message with others
        /// within the same conversation.
        /// </summary>
        object ConversationId { get; }

        /// <summary>
        /// Gets or sets a string identifier that describes the purpose or
        /// contents of this message.
        /// </summary>
        string Label { get; set; }

        /// <summary>
        /// Returns a value that indicates whether this message contains a
        /// value for the specified parameter.
        /// </summary>
        /// <typeparam name="T">
        /// The type of the value of the specified parameter.
        /// </typeparam>
        /// <param name="parameter">
        /// The parameter for which to check.
        /// </param>
        /// <returns>
        /// True if a value is present; otherwise false.
        /// </returns>
        bool HasValue<T>(IParameter<T> parameter);

        /// <summary>
        /// Extracts the value of the specified parameter from the message.
        /// </summary>
        /// <typeparam name="T">
        /// The type of the parameter value; this should be inferred from
        /// <paramref name="parameter"/>.
        /// </typeparam>
        /// <param name="parameter">
        /// A parameter descriptor that identifies which value to extract.
        /// </param>
        /// <returns>
        /// A value of type <typeparamref name="T"/>.
        /// </returns>
        /// <exception cref="Lite.Messaging.ParameterNotFoundException">
        /// The parameter was not found in this message.
        /// </exception>
        T GetValue<T>(IParameter<T> parameter);

        /// <summary>
        /// Copy the contents of this message to the specified sendable
        /// message.
        /// </summary>
        /// <param name="message">
        /// The destination message.
        /// </param>
        /// <exception cref="Lite.Messaging.IncompatibleMessageTypeException">
        /// The destination message type is compatible with this instance.
        /// </exception>
        void CopyTo(ISendMessage message);

        /// <summary>
        /// Returns a value that indicates whether this message can be copied
        /// to a specified destination message.
        /// </summary>
        /// <param name="message">
        /// The destination message.
        /// </param>
        /// <returns>
        /// True if the message types are compatible; otherwise false.
        /// </returns>
        bool CanCopyTo(ISendMessage message);
    }
}
